package com.ts.opengl

import android.content.Context
import android.graphics.Bitmap
import android.opengl.GLES20.GL_FRAMEBUFFER
import android.opengl.GLES20.GL_LINEAR
import android.opengl.GLES20.GL_NEAREST
import android.opengl.GLES20.GL_TEXTURE0
import android.opengl.GLES20.GL_TEXTURE_2D
import android.opengl.GLES20.GL_TEXTURE_MAG_FILTER
import android.opengl.GLES20.GL_TEXTURE_MIN_FILTER
import android.opengl.GLES20.GL_UNSIGNED_INT
import android.opengl.GLES20.glActiveTexture
import android.opengl.GLES20.glBindFramebuffer
import android.opengl.GLES20.glBindTexture
import android.opengl.GLES20.glTexParameteri
import android.opengl.GLES20.glUseProgram
import android.opengl.GLES20.glViewport
import android.opengl.GLES30
import android.opengl.GLUtils
import com.ts.audiocamera.R
import com.ts.opengl.simpleDraw.openglUtil
import com.ts.utils.EGL.EGLutil
import java.nio.FloatBuffer
import java.nio.IntBuffer

class EGL(){

    var vertex= floatArrayOf(
        // positions         //color              // texture coords
        -1.0f,  -1.0f, 0.0f,   1.0f, 0.0f, 0.0f,    1.0f, 1.0f, // top right
        1.0f, -1.0f, 0.0f,   1.0f, 0.0f, 1.0f,   0.0f, 1.0f, // bottom right
        -1.0f, 1.0f, 0.0f,   1.0f, 0.0f, 1.0f,   1.0f,0.0f, // bottom left
        1.0f,  1.0f, 0.0f,   0.0f, 0.5f, 1.0f,   0.0f, 0.0f, // top left
    )


    var vertexffbo= floatArrayOf(
        // positions         //color              // texture coords
        -1.0f,  -1.0f, 0.0f,   1.0f, 0.0f, 0.0f,    1.0f, 0.0f, // top right
        1.0f, -1.0f, 0.0f,   1.0f, 0.0f, 1.0f,   0.0f, 0.0f, // bottom right
        -1.0f, 1.0f, 0.0f,   1.0f, 0.0f, 1.0f,   1.0f,1.0f, // bottom left
        1.0f,  1.0f, 0.0f,   0.0f, 0.5f, 1.0f,   0.0f, 1.0f, // top left
    )
    var imagetextture=IntArray(1)
    var fbotextture=IntArray(1)
    var element= intArrayOf(
        0, 1, 2,
        1, 2, 3

    )
    var egLutil=EGLutil()
    val vertexFloat: FloatBuffer by lazy {
        openglUtil.createFloatBuffer(vertex)
    }

    var framebuffers=IntArray(1)

    var program=0;
    fun draw(width:Int,height:Int){
        glViewport(0, 0, width,height);
        glUseProgram(program)
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffers[0]);

        GLES30.glBindVertexArray(vao[0])
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, imagetextture[0]);

        GLES30.glDrawElements(GLES30.GL_TRIANGLE_STRIP,6, GL_UNSIGNED_INT,0)
        GLES30.glBindVertexArray(0)
        glBindTexture(GL_TEXTURE_2D, 0);
    }



    fun setImageView(bitmap: Bitmap){
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,imagetextture[0])
        GLUtils.texImage2D(GL_TEXTURE_2D,0,bitmap,0)
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,0)

        GLES30.glGenFramebuffers(framebuffers.size,framebuffers,0)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER,framebuffers[0])
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,fbotextture[0])

        GLES30.glFramebufferTexture2D(GLES30.GL_FRAMEBUFFER,GLES30.GL_COLOR_ATTACHMENT0,GLES30.GL_TEXTURE_2D,fbotextture[0],0)
        GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D,0,GLES30.GL_RGBA,bitmap.width,bitmap.height,0,GLES30.GL_RGBA,GLES30.GL_UNSIGNED_BYTE,null);
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,0)
        GLES30.glBindFramebuffer(GLES30.GL_FRAMEBUFFER,0)
    }

    fun createTexture(){
        GLES30.glGenTextures(imagetextture.size,imagetextture,0)
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,imagetextture[0])
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glBindTexture(GL_TEXTURE_2D, 0)

        GLES30.glGenTextures(fbotextture.size,fbotextture,0)
        GLES30.glBindTexture(GLES30.GL_TEXTURE_2D,fbotextture[0])
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glBindTexture(GL_TEXTURE_2D, 0)

    }

    val vertexFloatFbo: FloatBuffer by lazy {
        openglUtil.createFloatBuffer(vertexffbo)
    }
    val elementInt: IntBuffer by lazy {
        openglUtil.createIntBuffer(element)
    }
    var vao=IntArray(2)
    var vbo=IntArray(2)
    var ebo=IntArray(2)
    fun init(context: Context){
        //初始化环境
        egLutil.initEgl();

        program=openglUtil.createProgram(context, R.raw.fbo_new_ver,R.raw.fbo2_new_frag)
        createVBuffer()
        createTexture()








    }

    fun createVBuffer(){
        GLES30.glGenVertexArrays(vao.size,vao,0)
        GLES30.glGenBuffers(vbo.size,vbo,0)

        GLES30.glBindVertexArray(vao[0])
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,vbo[0])
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,vertexFloat.capacity()*4,vertexFloat, GLES30.GL_STATIC_DRAW);

        vertexFloat.position(0);
        GLES30.glVertexAttribPointer(0,3, GLES30.GL_FLOAT,false,8*4,0)
        GLES30.glEnableVertexAttribArray(0)

        vertexFloat.position(3);
        GLES30.glVertexAttribPointer(1,3, GLES30.GL_FLOAT,false,8*4,3*4)
        GLES30.glEnableVertexAttribArray(1)

        vertexFloat.position(6);
        GLES30.glVertexAttribPointer(2,2, GLES30.GL_FLOAT,false,8*4,6*4)
        GLES30.glEnableVertexAttribArray(2)

        GLES30.glGenBuffers(ebo.size,ebo,0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER,ebo[0])
        GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER,elementInt.capacity()*4,elementInt,GLES30.GL_STATIC_DRAW)


        GLES30.glBindVertexArray(0)
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER,0)


        GLES30.glBindVertexArray(vao[1])
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,vbo[1])
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,vertexFloatFbo.capacity()*4,vertexFloatFbo,GLES30.GL_STATIC_DRAW);

        vertexFloat.position(0);
        GLES30.glVertexAttribPointer(0,3,GLES30.GL_FLOAT,false,8*4,0)
        GLES30.glEnableVertexAttribArray(0)

        vertexFloat.position(3);
        GLES30.glVertexAttribPointer(1,3,GLES30.GL_FLOAT,false,8*4,3*4)
        GLES30.glEnableVertexAttribArray(1)

        vertexFloat.position(6);
        GLES30.glVertexAttribPointer(2,2,GLES30.GL_FLOAT,false,8*4,6*4)
        GLES30.glEnableVertexAttribArray(2)

        GLES30.glGenBuffers(ebo.size,ebo,0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER,ebo[1])
        GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER,elementInt.capacity()*4,elementInt,GLES30.GL_STATIC_DRAW);

        GLES30.glBindVertexArray(0)
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER,0)
        GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER,0)
    }

}
